import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ComputeNodeManager
{
    public static void main(String[] args)
    {
        new Thread(new CloudWatch()).start();
        try
        {
            ServerSocket serverSoc = new ServerSocket(FileTransferer.fileport);
            while (true)
            {
                Socket soc = serverSoc.accept();
                new Thread(new Worker(soc)).start();
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    private static class CloudWatch implements Runnable
    {

        @Override
        public void run()
        {
            try
            {
                ServerSocket serverSoc = new ServerSocket(CPUMonitor.port);
                while (true)
                {
                    Socket soc = serverSoc.accept();
                    ObjectOutputStream out = new ObjectOutputStream(soc.getOutputStream());
                    out.writeDouble(CPUMonitor.getInstance().getAvg());
                    out.close();
                    soc.close();
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }

    }

    private static class Worker implements Runnable
    {
        Socket soc;

        Worker(Socket soc)
        {
            this.soc = soc;
        }

        @Override
        public void run()
        {
            try
            {
                FileTransferer.FileData data = FileTransferer.receive(soc);
                soc.close();

                File file = new File(FileTransferer.savePath, data.name);
                
                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
                out.write(data.content);
                out.close();

                Logger.log("Attempting to execute command \"" + data.command + "\"");
                Process p = Runtime.getRuntime().exec(data.command, null, new File(FileTransferer.savePath));
                int exitValue;
                Thread.sleep(1000);
                try
                {
                    exitValue = p.exitValue();
                    Logger.log("Unsuccessful execution, exit code: " + exitValue);
                }
                catch (IllegalThreadStateException e)
                {
                    Logger.log("Successfully executed \"" + data.command + "\"");
                }

            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}
